package org.semanticflash.rdf.utils
{
	
	
	import com.bigflexlib.ds.container.zet.IRSet;
	import com.bigflexlib.ds.container.zet.IRWSet;
	import com.bigflexlib.ds.container.zet.impl.RWDictionarySet;
	import com.bigflexlib.x.String.StringUtil;
	
	import org.semanticflash.rdf.triple.RDFTriple;
	import org.semanticflash.rdf.triple.RDFTriplePattern;
	import org.semanticflash.rdf.values.IRI;
	
	
	
	
	
	/**
	 * 
	 * Static methods that are used throghout the RDF test cases.
	 * Instead of using complex IRIs we use letters and conventions.
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */	
	public class RDFTestingUtil
	{



		/**
		 * 
		 * a string containing the fictitious urn char namespace ( "urn:char:" )
		 * 
		 * 
		*/
		public static const URN_CHAR_NS:String = "urn:char:";




		/**
		 * 
		 * Returns an iri in the fictitious urn namespace "char".
		 * 
		 * <pre>
		 * 
		 * a --> urn:char:a
		 * b --> urn:char:b
		 * 
		 * etc...
		 * 
		 * </pre>
		 * 
		 * @param char
		 * @return 
		 * 
		 */		
		public static function parseCharIRI( char:String ):IRI
		{
			return IRI.instance( URN_CHAR_NS + char );
		}		
		
		
		
		/**
		 * 
		 * Asterisks (*) are used to represent wildcards.
		 * 
		 * @param chars
		 * 
		 * @return 
		 * 
		 */		
		public static function parseCharTriple( threeChars:String ):RDFTriple
		{
		
			var arr:Array = StringUtil.toCharArray( threeChars );
			
			var s:IRI = arr[0] == "*" ? null : parseCharIRI( arr[0] );
			var p:IRI = arr[1] == "*" ? null : parseCharIRI( arr[1] );
			var o:IRI = arr[2] == "*" ? null : parseCharIRI( arr[2] );
		
			return RDFTriple.instance( s, p, o );
		
		}
		
		

		/**
		 * 
		 * Variables are named in upper case
		 * 
		 * @param threeChars
		 * @return 
		 * 
		 */		
		public static function parseCharTriplePattern( threeChars:String ):RDFTriplePattern
		{
			var arr:Array = StringUtil.toCharArray( threeChars );
			var s:* = arr[0];
			var p:* = arr[1];
			var o:* = arr[2];
			if ( ! isUpperCase( String(s) ) ) s = parseCharIRI( s );
			if ( ! isUpperCase( String(p) ) ) p = parseCharIRI( p );
			if ( ! isUpperCase( String(o) ) ) o = parseCharIRI( o );
			return RDFTriplePattern.instance( s, p, o );
		}
		
		

		
//		/**
//		 * 
//		 * separated by commas
//		 * 
//		 * @param str
//		 * @return 
//		 * 
//		 */		
//		public static function parseCharBasicGraphPattern( str:String ):RDFBasicGraphPattern
//		{
//			// remove WS
//			str = str.split(" ").join("");
//			
//			var tps:Array = [];			
//
//			for each ( var line:String in str.split(",") )
//				if ( line.length == 3 )
//					tps.push( parseCharTriplePattern( line ) );		
//
//			return new RDFBasicGraphPattern( tps );
//
//		}
		
		
		
		
		
		
		private static function isUpperCase( str:String ):Boolean
		{
			return ( str == str.toUpperCase() );
		}
		
		
		
//		/**
//		 * 
//		 * 
//		 * Solutions are separated by semicolons ( ; )
//		 * <pre>
//		 * abc , def, dff | Xc, Yd ; frt | Zt 
//		 * </pre>
//		 * 
//		 * The empty string will be parsed as ONE empty solution.
//		 * Passing NULL will return NO solutions ( empty set )
//		 * 
//		 * @param str
//		 * @return
//		 * 
//		 */		
//		public static function parseCharSolutions( str:String ):IRWSet
//		{
//			var slns:IRWSet = new RWDictionarySet( );
//			
//			if ( str == null )
//				return slns;
//			
//			var parts:Array = str.split(";");
//			for each ( var part:String in parts )
//				slns.add( parseCharSolution( part ) );
//			return slns;
//		}
		
		
		
//		/**
//		 * The syntax for a char solution is the following:
//		 * <pre>
//		 * abc , def, dff | Xc, Yd 
//		 * </pre>
//		 * 
//		 * This represents an RDFGPSolution with three char triples:
//		 * 
//		 * <pre>
//		 * abc, def, dff
//		 * </pre>
//		 * 
//		 * and two bindings
//		 * 
//		 * <pre>
//		 * X = c
//		 * Y = d
//		 * </pre>
//		 * 
//		 * @param str
//		 * @return 
//		 * 
//		 */		
//		public static function parseCharSolution( str:String ):RDFGPSolution
//		{
//			var parts:Array = str.split( "|" );
//			var triples:IRSet = parseCharTriples( parts[ 0 ] as String );
//			var bindings:Object = parts[1] ? parseCharBindings( parts[1] ) : { };
//			
//			return new RDFGPSolution( null, triples, bindings );
//		}
		
		
		
		
		public static function parseCharBindings( str:String ):Object
		{
			var bindings:Object = {};
			var parts:Array = str.split( "," ); 
			for each ( var part:String in parts )
			{
				part = part.split(" ").join(""); // remove WS
				if ( part.length == 2 )
				{
					bindings[ part.charAt(0) ] = parseCharIRI( part.charAt(1) );
				}
			}
			return bindings;
		}
		
		
		
	
		public static function parseCharTriples( str:String ):IRWSet
		{
			var triples:IRWSet = new RWDictionarySet( );
			var lines:Array = str.split( "," );	
			for each ( var line:String in lines )
			{
				
				line = line.split(" ").join(""); // remove WS
				
				if ( line.length != 3 ) // must be 3 characters
				{
					continue;
				}
				
				triples.add( parseCharTriple( line ) );		
			
			}
			return triples;		
		}
		




		public static function testTripleSetContent( tripleSet:IRSet, charTriples:String ):Boolean
		{
		
			return tripleSet.compare( parseCharTriples( charTriples ) ).isEqual;
		
		}











	}

}